// Copyright (c) Huawei Technologies Co., Ltd. 2025. All rights reserved.
// This source file is part of the Cangjie project, licensed under Apache-2.0
// with Runtime Library Exception.
//
// See https://cangjie-lang.cn/pages/LICENSE for license information.

#ifndef CANGJIE_MIGRATOR_FILE_CONTENT
#define CANGJIE_MIGRATOR_FILE_CONTENT

#include <vector>

#include "Actions/Replace.h"
#include "Path.h"
#include "PositionRange.h"
#include "FileImportInfo.h"

namespace CangjieMigrator {

struct StringRange {
    size_t start;
    size_t end;

    [[nodiscard]] bool IsValid() const;
    [[nodiscard]] size_t Length() const;
};

class FileContent {
public:
    virtual ~FileContent() = default;

    [[nodiscard]] virtual size_t GetPositionIndex(const Cangjie::Position &position) const = 0;
    [[nodiscard]] virtual StringRange GetStringRange(const PositionRange &range) const = 0;
    [[nodiscard]] virtual std::string operator[](const PositionRange &range) const = 0;

    [[nodiscard]] virtual std::string SubStr(size_t index, size_t length) const = 0;
    [[nodiscard]] virtual std::string SubStr(StringRange range) const = 0;

    virtual void Apply(std::vector<Actions::Action> actions) = 0;
    virtual void Apply(const FileImportInfo::Result &importResult) = 0;
    virtual bool WriteTo(const Path &file) const = 0;
};

class FileContentLine final : public FileContent {
public:
    explicit FileContentLine(const Path &file);

    [[nodiscard]] size_t GetPositionIndex(const Cangjie::Position &position) const override;
    [[nodiscard]] StringRange GetStringRange(const PositionRange &range) const override;
    [[nodiscard]] std::string operator[](const PositionRange &range) const override;

    [[nodiscard]] std::string SubStr(size_t index, size_t length) const override;
    [[nodiscard]] std::string SubStr(StringRange range) const override;

    void Apply(std::vector<Actions::Action> actions) override;
    void Apply(const FileImportInfo::Result &importResult) override;
    bool WriteTo(const Path &file) const override;

private:
    // index / lineStarts[index]
    // 1/0 : package xxxxx
    // 2/14:
    // 3/15: import std.aaaaa.*
    // 4/34: import std.bbbbbb.*
    // 5/54:
    // 6/55: main() {
    // 7/64:     println("Hello World!")
    // 8/92: }
    // 9/94:

    static std::vector<size_t> GenerateLineStarts(const std::string &content);

    void Apply(const Actions::Replace &replace);
    void Apply(const Actions::Comment &comment);

    bool needToRemoveEndLine;
    std::string content;
    std::vector<size_t> lineStarts;
};

} // namespace CangjieMigrator

#endif // CANGJIE_MIGRATOR_FILE_CONTENT
